'use strict'

let underscore = require('underscore')
let templateConfig = require('../../config/templateConfig')
let itemComponent = require('./itemComponent')
let PackageComponent = require('./packageComponent')
let playerDao = require('../dao/playerDao')
let characterConfig = templateConfig.character[100001]
let pushMsg = require('../nodeapp/pushMsg')
  //角色基础信息
class BasicInfo {
  constructor(opts) {
    this.type = opts.type || 10 // 32怪物31野外boss
    this.money = opts.money || 0 //当前铜钱
    this.gold = opts.gold || 0 //金币
    this.sceneId = opts.sceneId || 260001 //角色所在的公共场景
    this.state = opts.state || 1 //玩家的状态 2初始状态
    this.abyssProcess = opts.abyssProcess || 1 //无尽深渊进度
    this.preciousLattice = opts.preciousLattice || 0 //藏宝图
    this.secretMap = opts.secretMap || 0
    this.secretMapId = opts.secretMapId || 0
    this.lattice = opts.lattice || 0 //人物处在的格子
    this.mapIndex = opts.mapIndex || 1 //1营地,2秘境入口,3秘境地图,4秘境守护之地
    this.lvl = opts.lvl || 1 //冒险等级
    this.expLvl = opts.expLvl || 0 //当前经验
    this.attriPoint = opts.attriPoint || 0 //属性技能点
    this.str = opts.str || 0 //分配的力量:提升基础攻击力和少量生命
    this.con = opts.con || 0 //分配的体质:提升防御和生命
    this.agile = opts.agile || 0 //分配的意志:提升物理技能伤害
    this.wisdom = opts.wisdom || 0 //分配的智慧:提升幸运和少量生命
    this.devilCaveIndex = opts.devilCaveIndex || 0 //魔窟层数
    this.luckyBuff = opts.luckyBuff || 0 //幸运buff
    this.moneyBuff = opts.moneyBuff || 0 //金钱buff
    this.maxHpBuff = opts.maxHpBuff || 0 //生命力buff
    this.stamina = opts.stamina || 0 //体力
    this.arenaTimes = opts.arenaTimes || 0 //免费竞技次数
    this.hp = opts.hp || 0 //玩家的血量
    this.maxHp = opts.maxHp || 0 //玩家的血量
    this.takeAlmsTimes = opts.takeAlmsTimes || 0 //每天免费领取补给品次数
  }
}

//基础属性
class BasicAttri {
  constructor(opts) {
    this.attack = opts.attack || 0 //攻击力
    this.maxHp = opts.maxHp || 0 //生命
    this.defend = opts.defend || 0 //防御
    this.critRate = opts.critRate || 0 //暴击概率
    this.critHurt = opts.critHurt || 0 //暴击伤害
    this.skillRate = opts.skillRate || 0 //技能释放率
    this.skillHurtPer = opts.skillHurtPer || 0 //技能伤害率
    this.str = opts.str || 0 //力量:提升基础攻击力和少量生命
    this.con = opts.con || 0 //体质:提升防御和生命
    this.agile = opts.agile || 0 //意志:提升物理技能伤害
    this.wisdom = opts.wisdom || 0 //智慧:提升幸运和少量生命
    this.lucky = opts.lucky || 0 //幸运值
    this.maxStamina = opts.maxStamina || 0 //最大体力
    this.ignoreDefend = opts.ignoreDefend || 0 //无视防御力
  }
}

//角色战斗属性
class FightAttri {
  constructor(opts) {
    this.hp = opts.hp || 0 //生命
    this.maxHp = opts.maxHp || 0 //最大生命
    this.attack = opts.attack || 0 //攻击力
    this.defend = opts.defend || 0 //防御
    this.critRate = opts.critRate || 0 //暴击概率
    this.critHurt = opts.critHurt || 0 //暴击伤害
    this.skillRate = opts.skillRate || 0 //技能释放率
    this.skillHurtPer = opts.skillHurtPer || 0 //技能伤害率
    this.ignoreDefend = opts.ignoreDefend || 0 //无视防御力
    this.str = opts.str || 0 //力量:提升基础攻击力和少量生命
    this.con = opts.con || 0 //体质:提升防御和生命
    this.agile = opts.agile || 0 //意志:提升物理技能伤害
    this.wisdom = opts.wisdom || 0 //智慧:提升幸运和少量生命
    this.lucky = opts.lucky || 0 //幸运
    this.skills = opts.skills || []
    this.attackSkill = opts.attackSkill || [] //攻击触发技能
    this.defendSkill = opts.defendSkill || [] //防御触发技能
    this.buff = 0 //0初始状态
    this.debuff = 0 //0初始状态 1 眩晕
    this.lvl = opts.lvl || 1 //等级
    this.maxStamina = opts.maxStamina || 0 //最大体力
    this.money = opts.money || 0 //银币掉率
  }
}

//角色装备
class Equipments {
  constructor(opts) {
    this.weapon = opts.weapon || 0 //武器
    this.soul = opts.soul || 0 //魂器
    this.body = opts.body || 0 //身体
    this.hand = opts.hand || 0 //手
    this.foot = opts.foot || 0 //脚
    this.head = opts.head || 0 //头
    this.ring = opts.ring || 0 //戒指
    this.earring = opts.earring || 0 //耳环
  }
}

let basicAttri = new BasicAttri(characterConfig.basicAttri)

class PlayerComponent {
  constructor(opts) {
    this._id = opts._id || 0
    this.userId = opts.userId || ''
    this.name = opts.name || '' //角色名字
    this.templateId = opts.templateId || 100001 //模板id
    this.basicInfo = new BasicInfo(opts.basicInfo) //角色基础信息
    this.initAttri = opts.initAttri || {}
    this.bag = opts.bag || {} //背包
    this.adventureBag = opts.adventureBag || [] //冒险背包
    this.equipments = new Equipments(opts.equipments)
    this.fightAttri = new FightAttri({})
    this.trialInfo = opts.trialInfo || null //试炼之所
    this.secretMerchant = opts.secretMerchant || {} //神秘商店
    this.loginDay = opts.loginDay || 0 //登陆的当天
    this.cureBar = opts.cureBar || null //补给栏
  }

  //初始化角色信息
  initPlayer() {
    this.bag = new PackageComponent(this.bag) //初始化角色背包信息
    let equipments = this.equipments
    for (let e in equipments) {
      if (equipments[e]) {
        equipments[e] = itemComponent.getPropComponent(equipments[e])
      }
    }
    this.calcAttri()
  }

  //计算人物属性
  calcAttri() {
    let maxHp, hp
    if (this.fightAttri.maxHp) {
      maxHp = this.fightAttri.maxHp || 0
      hp = this.fightAttri.hp || 0
    } else {
      maxHp = this.basicInfo.maxHp || 0
      hp = this.basicInfo.hp || 0
    }

    this.fightAttri = new FightAttri({})
    this.calcBasicAttri() //人物基础属性
    this.calcEquipment() //装备
    this.calcLvlAttri() //计算等级加成属性
    this.calcAttriPoints() //所有的属性点加成
    this.calcSkill() //技能

    if (maxHp && hp) {
      this.fightAttri.hp = parseInt(hp * this.fightAttri.maxHp / maxHp)
    }
    this.fightAttri.maxHp = parseInt(this.fightAttri.maxHp * (1 + this.basicInfo.maxHpBuff))
    this.fightAttri.hp = parseInt(this.fightAttri.hp * (1 + this.basicInfo.maxHpBuff))
    if (this.fightAttri.hp > this.fightAttri.maxHp) {
      this.fightAttri.hp = this.fightAttri.maxHp
    }
  }

  getFightAttriCopy() {
    let fightAttri = new FightAttri(this.fightAttri)
    fightAttri.hp = this.fightAttri.hp
    return fightAttri
  }

  initFightAttri() {
    this.fightAttri.buff = 0
    this.fightAttri.debuff = 0
    return this.fightAttri
  }

  getAllFightAttriCopy() {
    let fightAttri = new FightAttri(this.fightAttri)
    fightAttri.hp = this.fightAttri.maxHp
    return fightAttri
  }

  getPlayerCopy() {
    let fightAttri = new FightAttri(this.fightAttri)
    fightAttri.hp = this.fightAttri.maxHp
    let player = {
      _id: this._id,
      name: this.name,
      fightAttri: fightAttri,
    }

    player.getAllFightAttriCopy = function() {
      let fightAttri = new FightAttri(this.fightAttri)
      fightAttri.hp = this.fightAttri.maxHp
      return fightAttri
    }

    return player
  }

  //计算基础属性
  calcBasicAttri(fightAttri) {
    fightAttri = fightAttri || this.fightAttri
    fightAttri.attack += basicAttri.attack //攻击力
    fightAttri.maxHp += basicAttri.maxHp //生命
    fightAttri.defend += basicAttri.defend //防御
    fightAttri.critRate += basicAttri.critRate //暴击概率
    fightAttri.critHurt += basicAttri.critHurt //暴击伤害
    fightAttri.skillRate += basicAttri.skillRate //技能释放率
    fightAttri.skillHurtPer += basicAttri.skillHurtPer //技能伤害率
    fightAttri.str += basicAttri.str + this.basicInfo.str + this.initAttri.str //力量
    fightAttri.con += basicAttri.con + this.basicInfo.con + this.initAttri.con //体质
    fightAttri.agile += basicAttri.agile + this.basicInfo.agile + this.initAttri.agile //意志
    fightAttri.wisdom += basicAttri.wisdom + this.basicInfo.wisdom + this.initAttri.wisdom //幸运
    fightAttri.lucky += this.basicInfo.luckyBuff
    fightAttri.money += this.basicInfo.moneyBuff
    fightAttri.lvl = this.basicInfo.lvl
    fightAttri.maxStamina += basicAttri.maxStamina
    fightAttri.ignoreDefend += basicAttri.ignoreDefend
  }

  //计算等级加成属性
  calcLvlAttri(fightAttri) {
    fightAttri = fightAttri || this.fightAttri
    let lvl = this.basicInfo.lvl - 1
    let lvlUpAttri = characterConfig.lvlUpAttri
    fightAttri.attack += lvlUpAttri.attack * lvl //攻击力
    fightAttri.maxHp += lvlUpAttri.maxHp * lvl //生命
    fightAttri.defend += lvlUpAttri.defend * lvl //防御
    fightAttri.critRate += lvlUpAttri.critRate * lvl //暴击概率
    fightAttri.critHurt += lvlUpAttri.critHurt * lvl //暴击伤害
    fightAttri.skillRate += lvlUpAttri.skillRate * lvl //技能释放率
    fightAttri.skillHurtPer += lvlUpAttri.skillHurtPer * lvl //技能释放率
    fightAttri.str += lvlUpAttri.str * lvl //力量
    fightAttri.con += lvlUpAttri.con * lvl //体质
    fightAttri.agile += lvlUpAttri.agile * lvl //意志
    fightAttri.wisdom += lvlUpAttri.wisdom * lvl //智慧
    fightAttri.lucky += lvlUpAttri.lucky * lvl
    fightAttri.maxStamina += lvlUpAttri.maxStamina * lvl
  }

  //所有的属性点加成
  calcAttriPoints(fightAttri) {
    fightAttri = fightAttri || this.fightAttri
    let config = characterConfig.str
    for (let i in config) {
      fightAttri[i] += fightAttri.str * config[i]
    }

    config = characterConfig.con
    for (let i in config) {
      fightAttri[i] += fightAttri.con * config[i]
    }
    config = characterConfig.agile
    for (let i in config) {
      fightAttri[i] += fightAttri.agile * config[i]
    }
    config = characterConfig.wisdom
    for (let i in config) {
      fightAttri[i] += fightAttri.wisdom * config[i]
    }
  }

  //计算人物穿戴的装备属性
  calcEquipment(fightAttri) {
    fightAttri = fightAttri || this.fightAttri

    for (let i in this.equipments) {
      let equipment = this.equipments[i]
      if (equipment) {
        for (let a in equipment.mainAttri) { //主属性
          fightAttri[a] += equipment.mainAttri[a]
        }
        for (let a in equipment.addAttri) { //附加属性
          fightAttri[a] += equipment.addAttri[a]
        }
        for (let a in equipment.specialAttri) { //特殊属性
          fightAttri[a] += equipment.specialAttri[a]
        }

        if (equipment.solt[0]) { //宝石属性
          let gemId = equipment.solt[0]
          let gemConfig = templateConfig.prop[gemId]
          let attri = gemConfig.attri
          let gemType = gemConfig.gemType
          if (equipment.templateId === 640000) { //头盔
            if (gemType === 1) {
              fightAttri.maxStamina += attri[2] //加成体力
            } else if (gemType === 2) {
              fightAttri.money += attri[2] //银币掉落
            } else if (gemType === 3) {
              fightAttri.lucky += attri[2] //幸运
            }
          } else if (equipment.templateId >= 510000 && equipment.templateId <= 550000) { //武器
            if (gemType === 1) {
              fightAttri.critHurt += attri[1]
            } else if (gemType === 2) {
              fightAttri.skillRate += attri[1]
            } else if (gemType === 3) {
              fightAttri.skillHurtPer += attri[1]
            }
          } else { //防具
            if (gemType === 1) {
              fightAttri.attack += attri[0]
            } else if (gemType === 2) {
              fightAttri.defend += attri[0]
            } else if (gemType === 3) {
              fightAttri.maxHp += attri[0]
            }
          }
        }
        //强化属性
        if (equipment.strengthenLvl > 0) {
          let strengthenAttri = templateConfig.strengthen[440000]
          for (let a in equipment.addAttri) { //附加属性
            fightAttri[a] += strengthenAttri[a] * equipment.strengthenLvl
          }
        }
      }
    }
  }

  //计算技能
  calcSkill(fightAttri) {
    fightAttri = fightAttri || this.fightAttri
    if (this.equipments && this.equipments.soul) {
      let skills = this.equipments.soul.skills
      fightAttri.skills = skills.slice(0)
      for (let i in skills) {
        let skillId = skills[i]
        let skillType = templateConfig.skill[skillId].skillType
        if (skillType === 1) {
          fightAttri.attackSkill.push(skillId)
        } else if (skillType === 2) {
          fightAttri.defendSkill.push(skillId)
        } else if (skillType === 3) {
          switch (skillId) {
            case 450201: //致命 增加5%暴击率和等级*1暴击伤害率
              fightAttri.critRate += 5
              fightAttri.critHurt += this.basicInfo.lvl * 2
              break
            case 450202: //强身 增加20%的防御力
              fightAttri.defend += Math.ceil(this.fightAttri.defend * 0.2)
              break
            case 450203: //坚毅 增加30%的血量
              fightAttri.maxHp += Math.ceil(this.fightAttri.maxHp * 0.3)
              break
            case 450204: //巨力 增加20%的攻击力
              fightAttri.attack += Math.ceil(this.fightAttri.attack * 0.2)
              break
          }
        }
      }
      let len = this.fightAttri.attackSkill.length + this.fightAttri.defendSkill.length
      this.fightAttri.skillRate += len * characterConfig.oneSkiillRate
    }
  }

  //判断是否每天第一次登陆
  isFirstLoginEveryDay() {
    let dayTime = Math.floor(new Date().getTime() / 86400000)
    if (this.loginDay !== dayTime) {
      this.loginDay = dayTime
      this.basicInfo.arenaTimes = 10
      this.basicInfo.takeAlmsTimes = 10
    }
  }

  lvlup(getExp) {
    this.basicInfo.expLvl += getExp
    let lvl = this.basicInfo.lvl
    let lvlexp = characterConfig.lvlexp
    let needExp = lvlexp[lvl - 1]
    if (this.basicInfo.expLvl >= needExp) {
      this.basicInfo.lvl += 1
      this.basicInfo.attriPoint += characterConfig.lvlUpAttri.attriPoint
      this.basicInfo.expLvl -= needExp
      this.calcAttri()
      pushMsg.lvlup(this._id, {
        lvl: this.basicInfo.lvl
      })
    }
  }


  save() {
    playerDao.savePlayerById(this._id, this, function(err, ret) {})
  }
}

module.exports = PlayerComponent
